﻿#pragma once

#include "land_base_conf.h"
#include "land_thread.h"

enum {
    LAND_PTYPE_SEND,
    LAND_PTYPE_RESP,
    LAND_PTYPE_STARTUP,
    LAND_PTYPE_TIMEOUT,
    LAND_PTYPE_SOCKET,
};
enum {
    LAND_SOCKET_CONNECT,
    LAND_SOCKET_ACCEPT,
    LAND_SOCKET_READ,
    LAND_SOCKET_ERROR,
};

enum {
    LAND_FAMILY_IPV0,
    LAND_FAMILY_IPV4,
    LAND_FAMILY_IPV6,
};

enum {
    LAND_PROTOCOL_TCP,
    LAND_PROTOCOL_UDP,
};

typedef struct {
    unsigned workerCount;
    unsigned timerSleep;
}LandBase;

typedef struct LandList LandList;
typedef struct LandStorage LandStorage;
typedef LandHandle LandService;
// typedef enum LandHashType{
//     LPHASH_AP = 0,
//     LPHASH_RS,
//     LPHASH_JS,
//     LPHASH_PJW,
//     LPHASH_ELF,
//     LPHASH_BKDR,
//     LPHASH_SDBM,
//     LPHASH_DJB,
//     LPHASH_DEK,
// }LandHashType;
// typedef struct LPMap LPMap;
// typedef int (* LPMapKeyCompare)
//     (const void * k1, size_t sz1, const void * k2, size_t sz2);
// typedef uint32_t (* LPMapKeyHash)(const char * k, size_t sz);


typedef void (*LandRefFree)(void* ref);
typedef struct LandRef LandRef;
struct LandRef {
    int ref;
    LandRefFree free;
    LandRef* gcNext;
};

typedef struct {
    int ptype;
    LandService from;
    LandSession session;
    void* data;
    size_t size;
    void (*free)(void*);
}LandMsgSend;
typedef struct {
    void* ud;
    LandService self;
    LandMsgSend send;
}LandMsg;

typedef void (*LandExitSvrCallback)(LandService h, void* ud);
typedef void (*LandMsgCallback)(LandMsg* msg);

typedef struct LandSocketEvent LandSocketEvent;
struct LandSocketEvent{
    LAND_FD fd;
    void * ud;
    int evt;
    LandSocketEvent * next;
};
typedef struct LandSocketPoll LandSocketPoll;
typedef struct LandSocketAttacher LandSocketAttacher;
typedef LandHandle LandSocket;
typedef union {
    struct sockaddr s;
    struct sockaddr_in v4;
    struct sockaddr_in6 v6;
}LandSocketAddr;
typedef struct {
    char ip[128];
    uint16_t port;
    int protocol;
    int family;
}LandSocketInfo;
typedef struct {
    int cmd;
    LandSocket so;
    char* data;
    size_t size;
    LandSocketAddr addr;
}LandSocketMsg;

LAND_BASE_API void
landDefaultBase(LandBase* config);
LAND_BASE_API int
landInitBase(LandBase* config);
LAND_BASE_API int
landStartBase();
LAND_BASE_API int
landExitBase();

LAND_BASE_API void*
landNewRef(size_t size, LandRefFree free);
LAND_BASE_API void
landFreeRef(void* ref);
LAND_BASE_API int
landRetainRef(void* ref);
LAND_BASE_API int
landReleaseRef(void* ref);
LAND_BASE_API int
landCountRef(void* ref);
LAND_BASE_API void
landAutoGcRef();

LAND_BASE_API LandList*
landNewList(size_t size, unsigned cap);
LAND_BASE_API void
landFreeList(LandList* list);
LAND_BASE_API void
landPushList(LandList* list, void* p, unsigned count);
LAND_BASE_API void
landClearList(LandList* list);
LAND_BASE_API void
landClearListCap(LandList* list);
LAND_BASE_API unsigned
landGetListTotal(LandList* list);
LAND_BASE_API void
landBeginList(LandList* list);
LAND_BASE_API int
landNextList(LandList* list, void** p, unsigned* count);
LAND_BASE_API void*
landGetListLast(LandList* list);

LAND_BASE_API LandStorage *
landNewStorage (unsigned elementSize, unsigned initCount);
LAND_BASE_API void
landFreeStorage (LandStorage * storage);
LAND_BASE_API LandHandle
landRegInStorage (LandStorage * storage, void ** p);
LAND_BASE_API void *
landFindInStorage (LandStorage * storage, LandHandle h);
LAND_BASE_API int
landRecInStorage (LandStorage * storage, LandHandle h);
LAND_BASE_API void
landExpandStorage (LandStorage * storage, uint32_t count);
LAND_BASE_API void
landBeginStorage(LandStorage * storage);
LAND_BASE_API int
landNextStorage(LandStorage * storage, LandHandle * h, void ** p);


//LAND_BASE_API uint32_t
//landHash(const char * k, size_t sz, LandHashType type);
//LAND_BASE_API uint32_t
//landMapHash(const char * k, size_t sz);
//LAND_BASE_API LPMap *
//landNewMap(uint32_t cap);
//LAND_BASE_API void
//landFreeMap(LPMap * map);
//LAND_BASE_API void
//landExpandMap(LPMap * map, uint32_t cap);
//LAND_BASE_API void
//landPutMap (LPMap * map,
//        const void * k, size_t ksz, const void * v);
//LAND_BASE_API int
//landDelMap (LPMap * map, const void * k, size_t ksz);
//LAND_BASE_API int
//landFindInMap (LPMap * map,
//        const void * k, size_t ksz, const void ** v);
//LAND_BASE_API size_t
//landCountMap (LPMap * map);
//LAND_BASE_API void
//landBeginMap (LPMap * map);
//LAND_BASE_API int
//landNextMap (LPMap * map,
//    const void ** k, size_t * ksz, const void ** v);


LAND_BASE_API LandService
landNewService (LandMsgCallback cb, void* ud);
LAND_BASE_API int
landDispatchService (LandService h);
LAND_BASE_API int
landAttachWorker (LandService h);
LAND_BASE_API int
landSend (LandService h, LandMsgSend* send);
LAND_BASE_API int
landNewSession (LandService h, LandSession* session);

LAND_BASE_API LandSocketPoll *
landNewSocketPoll ();
LAND_BASE_API void
landFreeSocketPoll (LandSocketPoll * poll);
LAND_BASE_API int
landRegInSocketPoll (LandSocketPoll * poll, LAND_FD fd, int e, void * ud);
LAND_BASE_API int
landDelInSocketPoll (LandSocketPoll * poll, LAND_FD fd);
LAND_BASE_API int
landSetEvtInSocketPoll (LandSocketPoll * poll,
            LAND_FD fd, int evt, void * ud);
LAND_BASE_API int
landWaitSocketPollEvt (LandSocketPoll * poll, 
    LandSocketEvent* evts, int max, int timeout);
LAND_BASE_API uint32_t
landCountSocketPoll (LandSocketPoll * poll);

LAND_BASE_API LandSocketAttacher*
landNewSocketAttacher (LandService attach);
LAND_BASE_API LandSocket
landBindAddr(LandSocketAttacher* attacher,
    const char * host, uint16_t port, int protocol, int family);
LAND_BASE_API int
landListenSocket (LandSocketAttacher* attacher, LandSocket so, int backlog);
LAND_BASE_API LandSocket
landConnectAddr(LandSocketAttacher* attacher,
        const char* host, uint16_t port, LandSession session);
LAND_BASE_API int
landAcceptSocket (LandSocketAttacher* attacher,
                LandSocket so, LandSession session);
LAND_BASE_API int
landReadSocket (LandSocketAttacher* attacher,
    LandSocket so, size_t size, LandSession session);
LAND_BASE_API int
landWriteSocket (LandSocketAttacher* attacher,
    LandSocket so, const char * buf, size_t size);
LAND_BASE_API int
landCloseSocket (LandSocketAttacher* attacher, LandSocket so);
LAND_BASE_API int
landForwardSocket (LandSocketAttacher* attacher,
                LandSocket so, LandSession session);
LAND_BASE_API int
landDispatchSocket(LandSocketAttacher* attacher);

// LAND_BASE_API uint64_t
// landNow (LPContext * context);
LAND_BASE_API uint64_t
landTime ();
LAND_BASE_API void
landTimeout (LandService h, LandSession session, uint32_t ms);
